package com.campus.counseling.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.counseling.entity.SysMenu;
import com.campus.counseling.model.mapper.SysMenuMapper;
import com.campus.counseling.model.vo.MenuVO;
import com.campus.counseling.model.vo.RouterVO;
import com.campus.counseling.model.vo.RouterMetaVO;
import com.campus.counseling.service.SysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import cn.hutool.core.bean.BeanUtil;
import java.util.*;

@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    private final SysMenuMapper menuMapper;

    @Override
    public List<MenuVO> getMenuTree() {
        List<SysMenu> menus = list(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getStatus, 1)
                .orderByAsc(SysMenu::getSort));
        return buildTree(menus);
    }

    @Override
    public List<MenuVO> getUserMenuTree(Long userId) {
        List<SysMenu> menus = menuMapper.selectUserMenus(userId);
        return buildTree(menus);
    }

    @Override
    public List<RouterVO> getUserRouters(Long userId) {
        List<SysMenu> menus = baseMapper.selectUserMenus(userId);
        return buildRouters(menus);
    }

    @Override
    public List<String> getPermissionsByUserId(Long userId) {
        return baseMapper.selectPermissionsByUserId(userId);
    }

    /**
     * 构建树形菜单
     */
    private List<MenuVO> buildTree(List<SysMenu> menus) {
        List<MenuVO> tree = new ArrayList<>();
        Map<Long, MenuVO> menuMap = new HashMap<>();
        
        // 转换为MenuVO并建立ID映射
        for (SysMenu menu : menus) {
            MenuVO menuVO = new MenuVO();
            BeanUtil.copyProperties(menu, menuVO);
            // 确保字段正确复制
            menuVO.setSort(menu.getSort());
            menuVO.setVisible(menu.getVisible());
            menuVO.setStatus(menu.getStatus());
            menuMap.put(menu.getId(), menuVO);
            
            if (menu.getParentId() == 0) {
                tree.add(menuVO);
            }
        }
        
        // 处理父子关系
        for (SysMenu menu : menus) {
            if (menu.getParentId() != 0) {
                MenuVO parent = menuMap.get(menu.getParentId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(menuMap.get(menu.getId()));
                }
            }
        }
        
        return tree;
    }

    /**
     * 构建前端路由
     */
    private List<RouterVO> buildRouters(List<SysMenu> menus) {
        List<RouterVO> routers = new ArrayList<>();
        // 先处理顶级菜单
        for (SysMenu menu : menus) {
            if (menu.getParentId() == 0 && menu.getType() != 2) { // 排除按钮
                RouterVO router = new RouterVO();
                router.setPath(getRouterPath(menu));
                router.setComponent(getComponent(menu));
                router.setName(menu.getName());
                router.setHidden(menu.getHidden());
                
                // 设置重定向
                if (menu.getRedirect() != null) {
                    router.setRedirect(menu.getRedirect());
                }
                
                // 设置meta信息
                RouterMetaVO meta = new RouterMetaVO();
                meta.setTitle(menu.getName());
                meta.setIcon(menu.getIcon());
                meta.setHidden(menu.getHidden() != null ? menu.getHidden() : false);
                router.setMeta(meta);
                
                // 处理子菜单
                List<RouterVO> children = getChildrenRouters(menus, menu.getId());
                router.setChildren(children);
                
                routers.add(router);
            }
        }
        return routers;
    }

    /**
     * 获取子路由
     */
    private List<RouterVO> getChildrenRouters(List<SysMenu> menus, Long parentId) {
        List<RouterVO> childrenRouters = new ArrayList<>();
        for (SysMenu menu : menus) {
            if (menu.getParentId().equals(parentId) && menu.getType() != 2) {
                RouterVO router = new RouterVO();
                router.setPath(menu.getPath());
                router.setComponent(menu.getComponent());
                router.setName(menu.getName());
                router.setHidden(menu.getHidden());
                
                RouterMetaVO meta = new RouterMetaVO();
                meta.setTitle(menu.getName());
                meta.setIcon(menu.getIcon());
                meta.setHidden(menu.getHidden() != null ? menu.getHidden() : false);
                router.setMeta(meta);
                
                // 递归处理子菜单
                List<RouterVO> children = getChildrenRouters(menus, menu.getId());
                if (!children.isEmpty()) {
                    router.setChildren(children);
                }
                
                childrenRouters.add(router);
            }
        }
        return childrenRouters;
    }

    /**
     * 获取路由地址
     */
    private String getRouterPath(SysMenu menu) {
        String path = menu.getPath();
        // 一级菜单以 / 开头
        if (menu.getParentId() == 0 && !path.startsWith("/")) {
            return "/" + path;
        }
        return path;
    }

    /**
     * 获取组件信息
     */
    private String getComponent(SysMenu menu) {
        if (menu.getParentId() == 0) {
            return menu.getComponent() == null ? "Layout" : menu.getComponent();
        }
        return menu.getComponent();
    }

    private RouterVO buildRouter(SysMenu menu) {
        RouterVO router = new RouterVO();

        // 1. 处理组件路径
        if (menu.getParentId() == 0L) {
            router.setComponent("Layout");
        } else {
            // 移除前后的/，统一路径格式
            String component = menu.getComponent();
            component = component.replaceAll("^/|/$", "");
            // 移除/index后缀
            component = component.replaceAll("/index$", "");
            router.setComponent(component);
        }

        // 2. 处理访问路径
        String path = menu.getPath();
        path = path.replaceAll("^/|/$", "");
        router.setPath(path);

        // 3. 设置路由名称
        router.setName(menu.getName());

        // 4. 设置路由元数据
        RouterMetaVO meta = new RouterMetaVO();
        meta.setTitle(menu.getTitle());
        meta.setIcon(menu.getIcon());
        meta.setHidden(menu.getHidden());
        router.setMeta(meta);

        return router;
    }

    @Override
    public boolean save(SysMenu menu) {
        // 设置默认值
        if (menu.getParentId() == null) {
            menu.setParentId(0L);
        }
        if (menu.getSort() == null) {
            menu.setSort(1);
        }
        if (menu.getVisible() == null) {
            menu.setVisible(1);
        }
        if (menu.getStatus() == null) {
            menu.setStatus(1);
        }
        return super.save(menu);
    }

    @Override
    public boolean updateById(SysMenu menu) {
        // 更新前检查
        if (menu.getId().equals(menu.getParentId())) {
            throw new RuntimeException("上级菜单不能选择自己");
        }
        return super.updateById(menu);
    }

    @Override
    public boolean removeById(Long id) {
        // 删除前检查是否有子菜单
        long count = count(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getParentId, id));
        if (count > 0) {
            throw new RuntimeException("存在子菜单,不允许删除");
        }
        return super.removeById(id);
    }
} 